package console

import (
	"duoke/model"
	"duoke/service"
	"duoke/utils/gconv"
	"duoke/utils/gfile"
	"duoke/utils/gmd5"
	"duoke/utils/gtime"
	"duoke/utils/redislib"
	"duoke/utils/request"
	"duoke/utils/response"
	"duoke/utils/storage"
	"duoke/utils/valid"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"net/http"
	"path/filepath"
	"time"
)

var Upload = new(uploadCtl)

type uploadCtl struct{}

// 上传文件
func (ctl *uploadCtl) File(c *gin.Context) {
	accountR, _ := service.Request.Account(c)
	// 基础
	_, headers, err := c.Request.FormFile("file")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
	}
	// 配置
	setting, err := service.Upload.Setting(c)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
	}
	// 文件后缀
	suffix := filepath.Ext(headers.Filename)
	// 保存路径
	setting.SavePath = "account/" + gconv.String(accountR.Id) + "/" + gtime.Date(9) + "/"
	// 保存名称
	setting.SaveName = gmd5.MustEncrypt(gconv.String(time.Now().Unix())+headers.Filename) + suffix
	// 限制大小，2M
	setting.LimitSize = 10
	// 限制文件后缀
	setting.LimitSuffix = "jpeg,jpg,png,gif,mp3,mp4"
	// 开始验证
	err = storage.Valid(headers, setting)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
	}
	// 储存文件
	var fileData *storage.StructFile
	if setting.Type == "local" {
		// 本地保存
		fileData, err = storage.Local.Save(c, setting)
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
			return
		}
	} else if setting.Type == "qiniu" {
		// 七牛云保存
		fileData, err = storage.Qiniu.Save(c, setting)
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
			return
		}
	} else if setting.Type == "cos" {
		// 腾讯云保存
		fileData, err = storage.Cos.Save(c, setting)
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
			return
		}
	} else if setting.Type == "oss" {
		// 阿里云保存
		fileData, err = storage.Oss.Save(c, setting)
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
			return
		}
	} else {
		c.JSON(http.StatusBadRequest, gin.H{"请先配置上传设置": err.Error()})
	}
	// 数据库保存
	fileData.GroupId = gconv.Int(c.PostForm("groupId"))
	err = service.Upload.Save(c, *fileData)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
		return
	}
	response.Success(c, "上传成功", fileData)
}

// 上传文件列表
func (ctl *uploadCtl) FileList(c *gin.Context) {
	var req model.ReqList
	if err := c.ShouldBind(&req); err != nil {
		response.Error(c, err.Error(), nil)
		return
	}
	list, total, err := service.Upload.List(c, req)
	if err != nil {
		response.Error(c, err.Error(), nil)
		return
	}
	response.Success(c, "", gin.H{"total": total, "list": list})
}

// 图片删除
func (ctl *uploadCtl) FileDel(c *gin.Context) {
	var req model.ReqUploadDel
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, valid.GetError(err.(validator.ValidationErrors), req), nil)
		return
	}
	// 配置
	setting, err := service.Upload.Setting(c)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
	}
	err = service.Upload.Del(c, req, setting)
	if err != nil {
		response.Error(c, err.Error(), nil)
		return
	}
	response.Success(c, "删除成功", nil)
}

// 上传证书
func (ctl *uploadCtl) Cert(c *gin.Context) {
	accountR, _ := service.Request.Account(c)
	_, headers, err := c.Request.FormFile("file")
	if err != nil {
		response.Error(c, err.Error(), nil)
	}
	// 文件后缀
	suffix := filepath.Ext(headers.Filename)
	// 默认保存路径
	storagePath := "./private/cert/"
	savePath := gconv.String(accountR.Id) + "/"
	saveName := gmd5.MustEncrypt(gconv.String(time.Now().Unix())+headers.Filename) + suffix
	// 创建目录
	err = gfile.MakeDir(storagePath + savePath)
	if err != nil {
		response.Error(c, err.Error(), nil)
	}
	// 保存文件到本地
	err = c.SaveUploadedFile(headers, storagePath+savePath+saveName)
	if err != nil {
		response.Error(c, err.Error(), nil)
	}
	response.Success(c, "", gin.H{"path": storagePath + savePath + saveName})
}

// 分组列表
func (ctl *uploadCtl) GroupList(c *gin.Context) {
	list, err := service.Upload.GroupList(c)
	if err != nil {
		response.Error(c, err.Error(), nil)
		return
	}
	response.Success(c, "", list)
}

// 保存分组
func (ctl *uploadCtl) GroupSave(c *gin.Context) {
	var req model.ReqUploadGroup
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, valid.GetError(err.(validator.ValidationErrors), req), nil)
		return
	}
	err := service.Upload.GroupSave(c, req)
	if err != nil {
		response.Error(c, err.Error(), nil)
		return
	}
	response.Success(c, "保存成功", nil)
}

// 移动文件至分组
func (ctl *uploadCtl) GroupMove(c *gin.Context) {
	var req model.ReqUploadGroupMove
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, valid.GetError(err.(validator.ValidationErrors), req), nil)
		return
	}
	err := service.Upload.GroupMove(c, req)
	if err != nil {
		response.Error(c, err.Error(), nil)
		return
	}
	response.Success(c, "移动成功", nil)
}

// 删除分组
func (ctl *uploadCtl) GroupDel(c *gin.Context) {
	req := request.JsonMap(c)
	err := service.Upload.GroupDel(c, gconv.Int(req["id"]))
	if err != nil {
		response.Error(c, err.Error(), nil)
		return
	}
	response.Success(c, "删除成功", nil)
}

// 删除分组
func (ctl *uploadCtl) FragmentUpload(c *gin.Context) {
	accountR, _ := service.Request.Account(c)
	// 基础
	_, headers, err := c.Request.FormFile("file")
	keyName := "FragmentUpload_" + headers.Filename
	redisGet := redislib.Redis.Get(c, keyName)
	var upload *storage.StructFile
	val := redisGet.Val()
	fmt.Println(val)
	if val != "" {
		if val == "upload" {
			response.Error(c, "该图片正在上传中，请稍后", nil)
			return
		} else {
			err = json.Unmarshal([]byte(val), &upload)
			if err != nil {
				response.Error(c, err.Error(), nil)
				return
			}
			response.Success(c, "上传成功", upload)
			return
		}
	}
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
	}
	setting, err := service.Upload.Setting(c)

	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
	}
	// 文件后缀
	suffix := filepath.Ext(headers.Filename)
	// 保存路径
	setting.SavePath = "account/" + gconv.String(accountR.Id) + "/" + gtime.Date(9) + "/"
	// 保存名称
	setting.SaveName = gmd5.MustEncrypt(gconv.String(time.Now().Unix())+headers.Filename) + suffix
	// 限制大小，2M
	setting.LimitSize = 10
	// 限制文件后缀
	setting.LimitSuffix = "jpeg,jpg,png,gif,mp3,mp4"
	upload, err = storage.Qiniu.FragmentUpload(c, setting)
	// 数据库保存
	upload.GroupId = gconv.Int(c.PostForm("groupId"))
	err = service.Upload.Save(c, *upload)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
		return
	}
	response.Success(c, "上传成功", upload)
}
